package com.mangguo.tingjian.account.service;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.google.common.collect.Lists;
import com.google.common.collect.Sets;
import com.mangguo.tingjian.account.dto.AuthorityDto;
import com.mangguo.tingjian.account.dto.MenuDto;
import com.mangguo.tingjian.account.entity.Menu;
import com.mangguo.tingjian.account.entity.User;
import com.mangguo.tingjian.account.mapper.AuthorityMapper;
import com.mangguo.tingjian.account.entity.Authority;
import com.mangguo.tingjian.account.mapper.MenuMapper;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.List;
import java.util.Objects;
import java.util.Optional;
import java.util.Set;
import java.util.stream.Collectors;

@Service
@Transactional
public class AuthorityService {

    @Resource
    private AuthorityMapper authorityMapper;

    @Resource
    private MenuMapper menuMapper;

    @Resource
    private MenuService menuService;

    @Transactional(rollbackFor= Exception.class)
    public boolean distribution(AuthorityDto authorityDto) {
        //删除原有权限
        authorityMapper.delete(new QueryWrapper<>(Authority.builder().deptId(authorityDto.getDeptId()).roleId(authorityDto.getRoleId()).build()));
        if (authorityDto.getMenuIds() == null || authorityDto.getMenuIds().size() == 0) {
            return true;
        }
        //补充父菜单
        Set<Long> allSet = Sets.newHashSet(authorityDto.getMenuIds());
        authorityDto.getMenuIds().forEach(menuId -> {
            Menu menu = menuMapper.selectById(menuId);
            if(menu.getParentId() != 0){
                addParentMenu(menu, allSet);
            }
        });

        allSet.forEach(menuId -> {
            Authority authority = Authority.builder()
                    .deptId(authorityDto.getDeptId())
                    .roleId(authorityDto.getRoleId())
                    .menuId(menuId)
                    .code(authorityDto.getDeptId() + "_" + authorityDto.getRoleId() + "_" + menuId).build();
            authorityMapper.insert(authority);
        });
        return true;
    }

    public AuthorityDto getAuthority(Integer deptId, Integer roleId){
        List<MenuDto> menuDtos = menuService.findOwnMenu(User.builder().deptId(deptId).roleId(roleId).build());
        if(menuDtos == null || menuDtos.size() == 0){
            return AuthorityDto.builder().deptId(deptId).roleId(roleId).build();
        }
        //将菜单转为[[],[],[],[]]这种格式，方便前端使用
        List<List<Long>> menuIdList = Lists.newArrayList();
        //app
        List<Long> appMenuList = Lists.newArrayList();
        //车载
        List<Long> carMenuList = Lists.newArrayList();
        //小程序
        List<Long> appletMenuList = Lists.newArrayList();
        //账户
        List<Long> accountMenuList = Lists.newArrayList();

        Optional<MenuDto> appMenuOptional = menuDtos.stream().filter(menuDto -> Objects.equals(menuDto.getCode(), "app")).findFirst();
        if(appMenuOptional.isPresent()){
            appMenuList.add(appMenuOptional.get().getId());
            addChildMenu(appMenuOptional.get(), appMenuList);
        }

        Optional<MenuDto> carMenuOptional = menuDtos.stream().filter(menuDto -> Objects.equals(menuDto.getCode(), "car")).findFirst();
        if(carMenuOptional.isPresent()){
            carMenuList.add(carMenuOptional.get().getId());
            addChildMenu(carMenuOptional.get(), carMenuList);
        }

        Optional<MenuDto> appletMenuOptional = menuDtos.stream().filter(menuDto -> Objects.equals(menuDto.getCode(), "applet")).findFirst();
        if(appletMenuOptional.isPresent()){
            appletMenuList.add(appletMenuOptional.get().getId());
            addChildMenu(appletMenuOptional.get(), appletMenuList);
        }

        Optional<MenuDto> accountMenuOptional = menuDtos.stream().filter(menuDto -> Objects.equals(menuDto.getCode(), "account")).findFirst();
        if(accountMenuOptional.isPresent()){
            accountMenuList.add(accountMenuOptional.get().getId());
            addChildMenu(accountMenuOptional.get(), accountMenuList);
        }
        menuIdList.add(appMenuList);
        menuIdList.add(carMenuList);
        menuIdList.add(appletMenuList);
        menuIdList.add(accountMenuList);
        return AuthorityDto.builder().deptId(deptId).roleId(roleId).menuIdList(menuIdList).build();
    }

    /**
     * 查询出所有父id，并加入到allSet中
     * @param menu
     * @param allSet
     */
    private void addParentMenu(Menu menu, Set<Long> allSet){
        if(menu.getParentId() != 0){
            Menu parentMenu = menuMapper.selectById(menu.getParentId());
            allSet.add(parentMenu.getId());
            addParentMenu(parentMenu, allSet);
        }
    }

    private void addChildMenu(MenuDto menuDto,List<Long> menuIds){
        if(menuDto.getChildrenMenus() != null && menuDto.getChildrenMenus().size() != 0){
            menuDto.getChildrenMenus().forEach(menu -> {
                menuIds.add(menu.getId());
                addChildMenu(menu, menuIds);
            });
        }
    }

}
